package com.loren.demo22.service;

import com.loren.demo22.entity.TaskDefine;
import lombok.AllArgsConstructor;
import org.quartz.*;
import org.springframework.stereotype.Service;

import java.util.Map;

@Service
@AllArgsConstructor
public class QuartzService {

    private final Scheduler scheduler;

    /**
     * 添加任务
     */
    public void addScheduleJob(TaskDefine taskDefine) throws SchedulerException {
        JobKey jobKey = taskDefine.getJobKey();
        JobDataMap jobDataMap = getJobDataMap(taskDefine.getJobDataMap());
        String description = taskDefine.getDescription();
        Class<? extends Job> jobClass = taskDefine.getJobClass();
        String cron = taskDefine.getCronExpression();
        JobDetail jobDetail = getJobDetail(jobKey, description, jobDataMap, jobClass);
        Trigger trigger = getTrigger(jobKey, description, jobDataMap, cron);
        this.scheduler.scheduleJob(jobDetail, trigger);
    }

    /**
     * 修改任务
     */
    public void updateScheduleJob(TaskDefine taskDefine) throws SchedulerException {
        JobKey jobKey = taskDefine.getJobKey();
        String cronExpression = taskDefine.getCronExpression();
        TriggerKey triggerKey = new TriggerKey(jobKey.getName(), jobKey.getGroup());
        CronTrigger cronTrigger = (CronTrigger) this.scheduler.getTrigger(triggerKey);
        JobDataMap jobDataMap = getJobDataMap(taskDefine.getJobDataMap());
        if (!cronTrigger.getCronExpression().equalsIgnoreCase(cronExpression)) {
            CronTrigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity(triggerKey)
                    .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
                    .usingJobData(jobDataMap)
                    .build();
            scheduler.rescheduleJob(triggerKey, trigger);
        }
    }

    /**
     * 暂停任务
     */
    public void pauseScheduleJob(JobKey jobKey) throws SchedulerException {
        this.scheduler.pauseJob(jobKey);
    }

    /**
     * 恢复任务
     */
    public void resumeScheduleJob(JobKey jobKey) throws SchedulerException {
        this.scheduler.resumeJob(jobKey);
    }

    /**
     * 删除任务
     */
    public void deleteScheduleJob(JobKey jobKey) throws SchedulerException {
        this.scheduler.deleteJob(jobKey);
    }

    public JobDataMap getJobDataMap(Map<String, Object> map) {
        return map == null ? new JobDataMap() : new JobDataMap(map);
    }

    public Trigger getTrigger(JobKey jobKey, String description, JobDataMap jobDataMap, String cron) {
        return TriggerBuilder.newTrigger()
                .withIdentity(jobKey.getName(), jobKey.getGroup())
                .withDescription(description)
                .usingJobData(jobDataMap)
                .startAt(DateBuilder.futureDate(10, DateBuilder.IntervalUnit.SECOND)) // 执行时间是在未来的多久后
                .withSchedule(
//                        CronScheduleBuilder.cronSchedule(cron).withMisfireHandlingInstructionDoNothing()
                        SimpleScheduleBuilder.simpleSchedule().withRepeatCount(0)
                )
                .build();
    }

    public JobDetail getJobDetail(JobKey jobKey, String description, JobDataMap jobDataMap, Class<? extends Job> jobClass) {
        return JobBuilder.newJob(jobClass)
                .withIdentity(jobKey)
                .withDescription(description)
                .usingJobData(jobDataMap)
                .requestRecovery()
                .storeDurably()
                .build();
    }
}
